package com.example.other.netty.test;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class NettyServer {
    public static void main(String[] args) {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();

        //指定线程类型、IO模型、连接读写处理逻辑
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
//                .option(ChannelOption.SO_BACKLOG, 1024)//给服务端的channel设置一些属性。这里表示用于系统临时存放已完成三次握手的请求的队列的最大长度，如果连接建立频繁，服务器处理创建新连接较慢，可以适当调大这个参数
//                .attr(AttributeKey.newInstance("serverName"), "nettyServer")//指定自定义属性
//                .handler(new ChannelInitializer<NioServerSocketChannel>() {
//                    //用于服务端启动过程中的一些逻辑
//                    @Override
//                    protected void initChannel(NioServerSocketChannel nioServerSocketChannel) throws Exception {
//                        System.out.println("服务端启动中。。。");
//                    }
//                })
//                .childAttr(AttributeKey.newInstance("clientKey"), "clientValue")//为每一个连接指定自定义属性
//                .childOption(ChannelOption.SO_KEEPALIVE, true)//childOption()给每条连接设置一些TCP底层相关的属性。这里是否开启tcp底层心跳机制
//                .childOption(ChannelOption.TCP_NODELAY, true)//要求实时性高，则关闭；要求少网络交互，则打开
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    //用于指定处理新连接数据的读写处逻辑
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        nioSocketChannel.pipeline().addLast(new FirstServerHandler());
                    }
                });
//        serverBootstrap.bind(8000);//绑定结果是异步的，但是接口有立即返回值
        bind(serverBootstrap, 8081);
    }

    /**
     * 自动绑定递增接口，直到绑定成功为止
     * @param serverBootstrap
     * @param port
     */
    public static void bind(final ServerBootstrap serverBootstrap, final int port){
        serverBootstrap.bind(port).addListener(future -> {
           if(future.isSuccess()){
               System.out.println("绑定成功:" + port);
           } else {
               System.out.println("绑定失败:" + port);
               bind(serverBootstrap, port+1);
           }
        });
    }
}
